package com.wn.consumer05;

import com.rabbitmq.client.Channel;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.core.ExchangeTypes;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.annotation.Exchange;
import org.springframework.amqp.rabbit.annotation.Queue;
import org.springframework.amqp.rabbit.annotation.QueueBinding;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;

import java.io.IOException;

/**
 * @author yellow Docter
 * @date 2023 -02-28
 * @desc
 */
@Component
@Slf4j
public class ConfirmConsumer {

    @RabbitListener(
            bindings = @QueueBinding(
                    value = @Queue(name = "queue-confirm"),
                    exchange = @Exchange(
                            name = "exchange-confirm",
                            type = ExchangeTypes.DIRECT
                    ),
                    key = "confirm.msg"
            )
    )
    // 参数1  接收到的消息
    // 参数2  channel    管道(mq连接的最小单位 (可以创建 交换机\队列))
    // 参数3  message    消息对象
    public void handlerMsg(String msg, Channel channel, Message message) throws IOException {
        log.info("消费者消费了消息:{}", msg);

        try {
            int i = 10 / 0;

            //消息的拒绝
            // channel.basicReject();
            //消息的同意
            // 消费者手动确认消息消费; 参数1：消息id；参数2：是否批量确认

            //message.getMessageProperties() 拿到消息的属性 getDeliveryTag()拿到id
            //false  是否批量处理
            channel.basicAck(
                    message.getMessageProperties().getDeliveryTag(),
                    false
            );
        } catch (Exception e) {
            e.printStackTrace();
            // 分析：消息消费失败了，希望把消息重投到队列中，再次进行消费，如果还是消费失败就拒绝消息
            // 获取消息是否是重投的标记
            Boolean redelivered = message.getMessageProperties().getRedelivered();
            if (redelivered) {
                // 重新投递的消息: 直接拒绝掉
                // 消息投递序号 是否将消息回退到队列
                channel.basicReject(
                        message.getMessageProperties().getDeliveryTag(), false);
                System.out.println("消息消费异常，消息作废...");

            } else {
                // 该消息没有被重新投递过, 进行重投
                // 消息投递序号  是否批量  是否将消息回退到队列
                channel.basicNack(message.getMessageProperties().getDeliveryTag(), false, true);
                System.out.println("消息消费异常，消息进行重投");
            }
        }

    }
}
